/**
  Generated main.c file from MPLAB Code Configurator

  @Company
    Microchip Technology Inc.

  @File Name
    main.c

  @Summary
    This is the generated main.c using PIC24 / dsPIC33 / PIC32MM MCUs.

  @Description
    This source file provides main entry point for system initialization and application code development.
    Generation Information :
        Product Revision  :  PIC24 / dsPIC33 / PIC32MM MCUs - 1.170.0
        Device            :  dsPIC33CH512MP508S1
    The generated drivers are tested against the following:
        Compiler          :  XC16 v1.61
        MPLAB 	          :  MPLAB X v5.45
*/

/*
    (c) 2020 Microchip Technology Inc. and its subsidiaries. You may use this
    software and any derivatives exclusively with Microchip products.

    THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
    EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
    WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
    PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION
    WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.

    IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
    INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
    WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
    BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
    FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
    ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
    THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.

    MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE
    TERMS.
*/

/**
  Section: Included Files
*/
#include "mcc_generated_files/system.h"
#include "mcc_generated_files/mcc.h"
#include "stdio.h"

uint16_t Tick500ms = 0;
uint16_t RcvFlag = false;

uint16_t valchannel_S1AN0;
uint16_t valchannel_S1AN1;
uint16_t valchannel_S1AN8;
uint16_t valchannel_S1AN11;

#define PGPER_350KHZ        5706    // 350kHz
#define PGPER_50KHZ         39992   // 50kHz
#define PGDEADTIME          800     // 200ns
#define PG1_PG2_DIFFERENC   1200    // 300ns

uint16_t state_period = 2;
uint16_t PeriodNew ;
uint16_t PeriodMain;
uint16_t PeriodSlave;
uint16_t PeriodSlaveBak;
uint16_t TriggerNew;
uint16_t update = 0;
uint16_t counter = 0;



void IO_RE9_CallBack(void)
{
    IO_RE1_Toggle();
}

void TMR1_CallBack(void)
{
    // Add your custom callback code here
    Tick500ms = 1;
}

void __attribute__ ( ( __interrupt__ , auto_psv ) ) _ADFLTR0Interrupt ( void )
{
    //Read the ADC value from the ADCBUF
    valchannel_S1AN0 = ADFL0DAT;

    //clear the channel_S1AN1 interrupt flag
    IFS7bits.ADFLTR0IF = 0;
}

void __attribute__ ( ( __interrupt__ , auto_psv ) ) _ADCAN1Interrupt ( void )
{
    //Read the ADC value from the ADCBUF
    valchannel_S1AN1 = ADCBUF1;

    //clear the channel_S1AN1 interrupt flag
    IFS5bits.ADCAN1IF = 0;
}

void __attribute__ ( ( __interrupt__ , auto_psv ) ) _ADCAN11Interrupt ( void )
{
    //Read the ADC value from the ADCBUF
    valchannel_S1AN8 = ADCBUF8;    
    valchannel_S1AN11 = ADCBUF11;

    //clear the channel_S1AN11 interrupt flag
    IFS6bits.ADCAN11IF = 0;
}

void PWM_Generator4_CallBack(void)
{
    // Add Application code here
     switch(state_period)
    {
    
        case 1:
        {
            counter++;            
            if(counter == 8)
            {
                PeriodSlaveBak = PG1PER;
            
                PeriodNew = PGPER_350KHZ;
                PeriodMain = PeriodSlaveBak;
                                  
                PG1PER = PeriodMain;
                PG2PER = PeriodMain;
                
                PG1DC = PeriodMain;
                PG2DC = PeriodMain;
                
                // 3/4 old + 1/4 new period
                PeriodSlave = (__builtin_muluu(PeriodSlaveBak, 768)>>10) + (__builtin_muluu(PeriodNew, 256)>>10);
                PG3PER = PeriodSlave;
                PG4PER = PeriodSlave;                           
                
                PG3DC = PeriodSlave;   
                PG4DC = PeriodSlave;               
                
                TriggerNew = (__builtin_muluu(PeriodMain, 512)>>10);
                PG2TRIGA = TriggerNew;
                
                PG1STATbits.UPDREQ = 1;                                
            }
            else if (counter == 9)
            {
                PeriodMain = PeriodNew;
                PeriodSlave = PeriodNew;
                
                PG1PER = PeriodMain;
                PG2PER = PeriodMain;                 
                PG3PER = PeriodSlave;
                PG4PER = PeriodSlave;
                
                PG1DC = PeriodMain;
                PG2DC = PeriodMain;
                PG3DC = PeriodSlave;
                PG4DC = PeriodSlave;             
                
                TriggerNew = (__builtin_muluu(PeriodMain, 512)>>10);
                PG2TRIGA = TriggerNew;
                
                PG1STATbits.UPDREQ = 1; 
               
                counter = 0; 
                state_period = 2;            
            }
            else
            {        
                PeriodNew = PGPER_50KHZ;
                PeriodMain = PeriodNew;
                
                PG1PER = PeriodNew;
                PG2PER = PeriodNew;
                PG3PER = PeriodNew;
                PG4PER = PeriodNew;
                PG5PER = PeriodNew;
                PG6PER = PeriodNew;                

                PG1DC = PeriodNew;
                PG2DC = PeriodNew; 
                PG3DC = PeriodNew;
                PG4DC = PeriodNew;
                PG5DC = PeriodNew;
                PG6DC = PeriodNew;            
                
                TriggerNew = (__builtin_muluu(PeriodMain, 512)>>10);
                PG2TRIGA = TriggerNew;
                PG3TRIGA = TriggerNew;
                
                PG1STATbits.UPDREQ = 1;                       
            }
            break;
        }
        case 2:
        {
            counter++;
            if(counter == 8)
            {
                PeriodSlaveBak = PG1PER;
            
                PeriodNew = PGPER_50KHZ;
                PeriodMain = PeriodSlaveBak;
                                  
                PG1PER = PeriodMain;
                PG2PER = PeriodMain;
                
                PG1DC = PeriodMain;
                PG2DC = PeriodMain;                
                
                // 3/4 old + 1/4 new period
                PeriodSlave = (__builtin_muluu(PeriodSlaveBak, 768)>>10) + (__builtin_muluu(PeriodNew, 256)>>10);
                PG3PER = PeriodSlave;
                PG4PER = PeriodSlave;                
                
                PG3DC = PeriodSlave;   
                PG4DC = PeriodSlave;         
                
                TriggerNew = (__builtin_muluu(PeriodMain, 512)>>10);
                PG2TRIGA = TriggerNew;
                
                PG1STATbits.UPDREQ = 1;
            }
            else if(counter == 9)
            {
                PeriodMain = PeriodNew;
                PeriodSlave = PeriodNew;
                
                PG1PER = PeriodMain;
                PG2PER = PeriodMain;                 
                PG3PER = PeriodSlave;
                PG4PER = PeriodSlave;
                
                PG1DC = PeriodMain;
                PG2DC = PeriodMain;
                PG3DC = PeriodSlave;
                PG4DC = PeriodSlave;            
                
                TriggerNew = (__builtin_muluu(PeriodMain, 512)>>10);
                PG2TRIGA = TriggerNew;
                
                PG1STATbits.UPDREQ = 1; 
               
                counter = 0; 
                state_period = 1;
            }
            else
            {
                PeriodNew = PGPER_350KHZ;
                PeriodMain = PeriodNew;
                
                PG1PER = PeriodNew;
                PG2PER = PeriodNew;
                PG3PER = PeriodNew;
                PG4PER = PeriodNew;            

                PG1DC = PeriodNew;
                PG2DC = PeriodNew; 
                PG3DC = PeriodNew;
                PG4DC = PeriodNew;         
                
                TriggerNew = (__builtin_muluu(PeriodMain, 512)>>10);
                PG2TRIGA = TriggerNew;
                
                PG1STATbits.UPDREQ = 1;                        
            }
            break;
        }
    }        
}

//void PWM_Generator4_CallBack(void)
//{
//    switch (state_period)
//    {
//        case 1:
//        {
//            counter++;
//
//            if (counter == 9)
//            {
//                PG1PER = PGPER_350KHZ;
//                PG2PER = PGPER_350KHZ;                 
//                PG3PER = PGPER_350KHZ;
//                PG4PER = PGPER_350KHZ;
//                
//                PG1DC = PGPER_350KHZ;
//                PG2DC = PGPER_350KHZ;
//                PG3DC = PGPER_350KHZ;
//                PG4DC = PGPER_350KHZ;
//                
//                PG2TRIGA = PGPER_350KHZ>>1;          
//                
//                PG1STATbits.UPDREQ = 1;
//                
//                counter = 0;
//                state_period = 2;
//            }
//            break;
//        }
//        
//        case 2:
//        {
//            counter++;
//
//            if (counter == 9)
//            {
//                PG1PER = PGPER_50KHZ;
//                PG2PER = PGPER_50KHZ;                 
//                PG3PER = PGPER_50KHZ;
//                PG4PER = PGPER_50KHZ;
//                
//                PG1DC = PGPER_50KHZ;
//                PG2DC = PGPER_50KHZ;
//                PG3DC = PGPER_50KHZ;
//                PG4DC = PGPER_50KHZ;
//                
//                PG2TRIGA = PGPER_50KHZ>>1;
//                
//                PG1STATbits.UPDREQ = 1;
//                
//                counter = 0;
//                state_period = 1;
//            }
//            break;
//        }
//    }
//}

/*
                         Main application
 */
int main(void)
{
    // initialize the device
    SYSTEM_Initialize();
    
    /****************************/
    IFS7bits.ADFLTR0IF = 0;
    IEC7bits.ADFLTR0IE = 1;
    /****************************/

    __builtin_write_RPCON(0x0000); // unlock PPS
    
    RPINR12bits.PCI8R = 8;      // Slave PWM Event Output C ->PWM:S1PCI8
    RPINR12bits.PCI9R = 9;      // Slave PWM Event Output D ->PWM:S1PCI9
    
    __builtin_write_RPCON(0x0800); // lock PPS   
    
    
    PG1PER = PGPER_350KHZ;
    PG2PER = PGPER_350KHZ;
    PG3PER = PGPER_350KHZ;
    PG4PER = PGPER_350KHZ;
    PG5PER = PGPER_350KHZ;
    PG6PER = PGPER_350KHZ; 

    PG1DC = PGPER_350KHZ;
    PG2DC = PGPER_350KHZ;
    PG3DC = PGPER_350KHZ;
    PG4DC = PGPER_350KHZ;
    PG5DC = PGPER_350KHZ;
    PG6DC = PGPER_350KHZ ;
    
    PG1PHASE = PGDEADTIME;
    PG2PHASE = PG1_PG2_DIFFERENC + PGDEADTIME;
    PG3PHASE = PGDEADTIME;     
    PG4PHASE = PG1_PG2_DIFFERENC + PGDEADTIME;
    PG5PHASE = PGDEADTIME;
    PG6PHASE = PG1_PG2_DIFFERENC + PGDEADTIME;
    
    PG1STATbits.UPDREQ = 1; 
    
    // all PGs are push-pull mode.
    // PG1 every 2 ADC trigger (0deg output one event C, PG2 indirect sync to event C.
    // PG2 every 2 ADC trigger (90deg output one event D, PG3/PG4 indirect sync to event D.
    // PG4 enable sync interrupt, and update these period, duty cycle and ADC trigger value. All these update must before next PG1 start of cycle.
    PWM_GeneratorEnable(PWM_GENERATOR_4);
    PWM_GeneratorEnable(PWM_GENERATOR_3);
    PWM_GeneratorEnable(PWM_GENERATOR_2);
    PWM_GeneratorEnable(PWM_GENERATOR_1);    
    
    INTERRUPT_GlobalEnable();
    
    while (1)
    {
        // Add your application code
        if (Tick500ms == 1)
        {
//            if (UART1_IsRxReady())
//            {
//                if (UART1_Read() == '1')
//                {
//                    RcvFlag = false;
//                }
//                else
//                {
//                    RcvFlag = true;
//                }            
//            }
//            
//            if (RcvFlag == true)
//            {
//                printf("Hello World!\r\n");
//            }
//            else
//            {
//                printf("I'm Here!\r\n");
//            }
        
//            printf("S1AN0 = %d\r\n", valchannel_S1AN0);
//            printf("S1AN1 = %d\r\n", valchannel_S1AN1);
//            printf("S1AN8 = %d\r\n", valchannel_S1AN8);
//            printf("S1AN11 = %d\r\n", valchannel_S1AN11);
            
            Tick500ms = 0;
        }
    }
    return 1; 
}

/**
 End of File
*/

